package com.yellowcong.shiro.realm;

import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import com.yellowcong.service.RolePermissionService;
import com.yellowcong.service.UserRoleService;
import com.yellowcong.service.UserService;
import com.yellowcong.shiro.model.User;

/**
 * 创建日期:2017年9月23日 <br/>
 * 创建用户:yellowcong <br/>
 * 功能描述:用于授权操作
 */
public class SampleRealm extends AuthorizingRealm {

	@Autowired
	private UserService userService;
	
	@Autowired
	private UserRoleService userRoleService;
	
	@Autowired
	private RolePermissionService rolePermissionService;

	/**
	 * 用户授权，当用户访问需要有权限的页面的情况，需要访问这个方法来获取权限列表
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection paramPrincipalCollection) {
		
		//用户名称
		Object username = paramPrincipalCollection.getPrimaryPrincipal();
		
		SimpleAuthorizationInfo info =  new SimpleAuthorizationInfo();
		// 根据用户ID查询角色（role），放入到Authorization里。
		Set<String> roles = userRoleService.getRoleByName(username.toString());
		info.setRoles(roles);
		
		// 根据用户ID查询权限（permission），放入到Authorization里。
		Set<String> permissions =  null;
		if(roles.size() >0) {
			permissions = this.rolePermissionService.getPermissionByRole(roles);
		}
		info.setStringPermissions(permissions);
		
		
		return info;
		
	}

	/**
	 * 认证，用户登录
	 * 登陆的时候，会调用这个
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken paramAuthenticationToken) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) paramAuthenticationToken;
		
		//数据库中，查询用户的信息
		User user = userService.login(token.getUsername());
		
		// token返回的是一个数组,将char类型转化为String类型
		//这个是web前台传递过来的值
		//这个密码的比对是通过Shiro自己给我们完成的
		//密码是通过AuthenticatingRealm.getCredentialsMatcher 的方式来进行比对的
		String pswDate = new String(token.getPassword());
		
		//当用户为空的情况
		if(user == null){
			// 当没有用户的时候，抛出异常
			throw new UnknownAccountException();
		}
		
		//第一个参数：用户名/用户对象
		String username =token.getUsername();
		//第二个参数：用户的密码
		String password = user.getPassword();
		
		//第三个参数：盐值(这个盐是 username)
		ByteSource solt = null;
		
		//第四个参数：获取这个Realm的信息
		String realmName =this.getName();
		
		//他们拿到密码web的密码，同数据库获取到的密码进行比对操作
		return new SimpleAuthenticationInfo(username, password, solt,realmName);
	}

}
